using System.Data.Linq;
using System.Linq;
using System.Web.Mvc;
using Htse.Blue.Logic;
using Htse.Blue.Logic.Validation;
using Htse.Blue.Models;
using Htse.Blue.Models.ViewModels;

namespace Htse.Blue.Controllers
{
	[HandleError(Order = 0)]
	public class UmpireController : Controller
	{
		private IUmpireService _umpireService;

		public UmpireController()
		{
			_umpireService = new UmpireService(new ModelStateWrapper<Umpire>(ModelState));
		}

		public UmpireController(IUmpireService umpireService)
		{
			_umpireService = umpireService;
		}

		[Authorize]
		public ActionResult Display(int? id)
		{
			var umpire = _umpireService.GetByAccountName(User.Identity.Name);

			if (umpire == null)
			{
				return View("NoUmpireForAccount");
			}

			UmpireDisplayViewModel viewModel = new UmpireDisplayViewModel(umpire, id ?? 1);

			if (Request.IsAjaxRequest())
			{
				return PartialView("DisplaySelector", viewModel);
			}
			else
			{
				return View("Display", viewModel);
			}
		}

		[Authorize(Roles = SiteConstants.ADMIN_ACCOUNT)]
		public ActionResult List(int? page, string sort)
		{
			var umpires = _umpireService.GetAll(page, SiteConstants.PAGE_SIZE, sort);

			if (Request.IsAjaxRequest())
			{
				return PartialView("GridUmpireList", umpires);
			}
			else
			{
				return View("List", umpires);
			}
		}

		[Authorize(Roles = SiteConstants.ADMIN_ACCOUNT)]
		public ActionResult Create()
		{
			return View("Create", BuildUmpireFormViewModel(new Umpire(), null, null));
		}

		[Authorize(Roles = SiteConstants.ADMIN_ACCOUNT)]
		[ValidateAntiForgeryToken]
		[AcceptVerbs(HttpVerbs.Post)]
		public ActionResult Create([Bind(Exclude = "Id")] Umpire umpire)
		{
			bool result = _umpireService.Create(umpire);

			if (result)
			{
				return RedirectToAction("List");
			}
			else
			{
				return View("Create", BuildUmpireFormViewModel(umpire, umpire.AccountName, null));
			}
		}

		[Authorize(Roles = SiteConstants.ADMIN_ACCOUNT)]
		public ActionResult FullEdit(int id)
		{
			Umpire umpire = _umpireService.GetById(id);

			if (umpire == null)
			{
				return View("NotFound");
			}

			return View("FullEdit", BuildUmpireFormViewModel(umpire, umpire.AccountName, umpire.AccountName));
		}

		[Authorize(Roles = SiteConstants.ADMIN_ACCOUNT)]
		[AcceptVerbs(HttpVerbs.Post)]
		[ValidateAntiForgeryToken]
		[HandleError(ExceptionType = typeof(ChangeConflictException), View = "ConcurrencyError")]
		public ActionResult FullEdit(Umpire umpire, string originalAccountName)
		{
			Umpire originalUmpire = new Umpire
			{
				Id = umpire.Id,
				ConcurrencyTimestamp = umpire.ConcurrencyTimestamp,
			};

			bool result = _umpireService.Update(umpire, originalAccountName);

			if (result)
			{
				return RedirectToAction("List");
			}
			else
			{
				return View("FullEdit", BuildUmpireFormViewModel(umpire, umpire.AccountName, originalAccountName));
			}
		}

		[Authorize]
		public ActionResult Edit(int id)
		{
			Umpire umpire = _umpireService.GetById(id);

			if (umpire == null)
			{
				return View("NotFound");
			}

			if (!ControllersHelper.IsCurrentUmpireTheCurrentUser(umpire, User))
			{
				return View("NotAllowed");
			}

			return View("Edit", BuildUmpireFormViewModel(umpire, umpire.AccountName, umpire.AccountName));
		}

		[Authorize]
		[AcceptVerbs(HttpVerbs.Post)]
		[ValidateAntiForgeryToken]
		[HandleError(ExceptionType = typeof(ChangeConflictException), View = "ConcurrencyError")]
		public ActionResult Edit(Umpire umpire, string originalAccountName)
		{
			if (!ControllersHelper.IsCurrentUmpireTheCurrentUser(umpire, User))
			{
				return View("NotAllowed");
			}

			bool result = _umpireService.Update(umpire, originalAccountName);

			if (result)
			{
				return RedirectToAction("Display");
			}
			else
			{
				return View("Edit", BuildUmpireFormViewModel(umpire, umpire.AccountName, originalAccountName));
			}
		}

		[Authorize(Roles = SiteConstants.ADMIN_ACCOUNT)]
		[AcceptVerbs(HttpVerbs.Delete)]
		[ActionName("Delete")]
		public ActionResult AjaxDelete(int id)
		{
			var umpireToDelete = _umpireService.GetById(id);

			_umpireService.Delete(umpireToDelete);

			return RedirectToAction("List");
		}

		private UmpireFormViewModel BuildUmpireFormViewModel(Umpire umpire, string selectedAccountName, string originalAccountName)
		{
			var accounts = new AccountMembershipService().ListAllUserNames();

			var umpires = _umpireService.GetAll();

			var availableAccounts = accounts.Except(umpires.Select(u => u.AccountName));

			if (string.IsNullOrEmpty(selectedAccountName))
			{
				if (string.IsNullOrEmpty(originalAccountName))
				{
					return new UmpireFormViewModel(umpire, availableAccounts);
				}
				else
				{
					var availableAccountsWithOriginal = availableAccounts.ToList();

					availableAccountsWithOriginal.Add(originalAccountName);

					return new UmpireFormViewModel(umpire, availableAccountsWithOriginal, originalAccountName, originalAccountName);
				}
			}
			else
			{
				var availableAccountsWithCurrent = availableAccounts.ToList();

				availableAccountsWithCurrent.Add(selectedAccountName);

				return new UmpireFormViewModel(umpire, availableAccountsWithCurrent, selectedAccountName, originalAccountName);
			}
		}
	}
}
